/*
 * Copyright (c) 2017,安徽皖通科技股份有限公司 All rights reserved.
 */

package com.wttech.dzzf.process.service.blacklist;

import com.wtkj.vo.dzzf.base.kfwd.OBU;
import com.wttech.dzzf.check.moduleSet.CheckVehicleUpload_9;
import com.wttech.dzzf.process.dao.GenerateBlObuInfosDao;
import com.wttech.dzzf.process.model.ObuTemp;
import com.wttech.dzzf.process.model.user.User;
import com.wttech.dzzf.process.service.base.BaseInfoService;
import com.wttech.dzzf.process.service.user.UserDetailInfosCreatorService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;

import static com.wttech.dzzf.process.constant.UserConstants.DEFAULT_PROCESS_NUM;
import static com.wttech.dzzf.process.constant.UserConstants.DEFAULT_VEHICLE_CHAR;
import static com.wttech.dzzf.process.constant.UserConstants.DEFAULT_VEHICLE_PLATE;

/**
 * 生成黑名单中未上传的OBU信息
 *
 * @author MaShibo
 * @date 2017/12/22.
 */
@Service
public class GenerateBlObuInfosService {

	private static final Logger LOGGER = LoggerFactory.getLogger(GenerateBlObuInfosService.class);

	@Resource
	private ThreadPoolTaskExecutor executor;

	@Resource
	private BaseInfoService baseInfoService;

	@Resource
	private GenerateBlObuInfosDao generateBlObuInfosDao;

	@Resource
	private GenerateBlObuInfoSubService generateBlObuInfoSubService;

	@Resource
	private UserDetailInfosCreatorService userDetailInfosCreatorService;


	private void process() {
		int total = generateBlObuInfosDao.queryObuTempNum(ObuTemp.STATE_UNUPLOAD);
		LOGGER.info("共【{}】条未上传的OBU信息", total);
		int corePoolSize = executor.getCorePoolSize();
		int maxInOneProcess = corePoolSize * DEFAULT_PROCESS_NUM;
		int processNum;
		int count;
		if (total < maxInOneProcess) {
			processNum = (int) Math.floor((double) total / corePoolSize);
			count = corePoolSize;
		} else {
			processNum = DEFAULT_PROCESS_NUM;
			count = (int) Math.ceil((double) total / processNum);
		}
		LOGGER.info("每次约处理【{}】条数据， 需要处理【{}】次", processNum, count);
		List<Future<Void>> futures = new ArrayList<>(count);
		for (int i = 0; i < count; i++) {
			int num = i + 1;
			futures.add(executor.submit(() -> {
				try {
					processOnceTime(num, processNum);
				} catch (Exception e) {
					LOGGER.error(e.getMessage(), e);
				}
				return null;
			}));
		}
		baseInfoService.getFutureResult(futures);
		executor.shutdown();
	}

	private void processOnceTime(int num, int processNum) {
		LOGGER.info("第【{}】次开始执行...", num);
		int startRow = (num - 1) * processNum + 1;
		int endRow = num * processNum;
		List<ObuTemp> temps = generateBlObuInfosDao.queryObuTempByRow(startRow, endRow);
		temps.forEach(temp -> {
			try {
				generateBlObuInfoSubService.processObuTemp(temp);
			} catch (Exception e) {
				LOGGER.error(e.getMessage(), e);
			}
		});
		LOGGER.info("第【{}】次结束执行...", num);
	}

	private void processObus(){
		LOGGER.info("生成OBU信息");
		int total = generateBlObuInfosDao.queryObuTempNum();
		LOGGER.info("共{}条数据待处理", total);
		int count = (int) Math.ceil((double)total/DEFAULT_PROCESS_NUM);
		LOGGER.info("需要执行{}次", count);
		List<Future<Void>> futures = new ArrayList<>(count);
		LOGGER.info("开始执行...");
		for (int i = 0; i < count; i ++){
			int num = i + 1;
			futures.add(executor.submit(() ->{
				int startRow = (num - 1) * DEFAULT_PROCESS_NUM + 1;
				int endRow = num * DEFAULT_PROCESS_NUM;
				List<ObuTemp> obuTemps = generateBlObuInfosDao.queryAllHavingUserIdObus(startRow, endRow);
				obuTemps.forEach(obuTemp -> {
					String obuId = obuTemp.getObuId();
					LOGGER.info("开始处理OBU【{}】", obuId);
					try {
						User user = new User();
						user.setId(obuTemp.getUserId());
						if (StringUtils.isBlank(user.getId())){
							user.setId("61010115081799999");
						}
						OBU obu = generateBlObuInfosDao.queryDzzfObuById(obuTemp.getObuId());
						if (obu != null){
							String vehPlate = obu.getVehiclePlate();
							Integer vehColor = obu.getVehicleColor();

							String vehicleId = vehPlate + DEFAULT_VEHICLE_CHAR + vehColor;
							String result = new CheckVehicleUpload_9().checkId(vehicleId);
							String finalVehicleId = baseInfoService.needOutput(result) ?
									DEFAULT_VEHICLE_PLATE + DEFAULT_VEHICLE_CHAR + 9 : vehicleId;

							userDetailInfosCreatorService.buildAndCreateObu(obu, user, finalVehicleId);
						}else {
							LOGGER.info("OBU【{}】没有对应的信息", obuId);
						}

					} catch (Exception e) {
						LOGGER.error(e.getMessage(), e);
					}
				});
				LOGGER.info("第{}次结束执行", num);
				return null;
			}));
		}
		baseInfoService.getFutureResult(futures);
		executor.shutdown();
	}

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		GenerateBlObuInfosService service = context.getBean(GenerateBlObuInfosService.class);
//		service.process();
		service.processObus();
	}
}
